<template>
  <!-- 新增修改推窗 -->
  <BaseDrawer
    width="540px"
    :title="drawerTitle"
    placement="right"
    v-model:visible="open"
    :maskClosable="false"
    @close="handleClose"
  >
    <template #default>
      <a-form
        v-if="open"
        ref="formRef"
        :model="formState"
        :rules="rules"
        :label-col="labelCol"
        :wrapper-col="wrapperCol"
      >
        <a-row>
          <a-col :span="24">
            <a-form-item :label="t('routes.role.roleName')" name="roleName">
              <a-input
                v-model:value="formState.roleName"
                :placeholder="t('routes.role.roleNamePlaceholder')"
              />
            </a-form-item>
          </a-col>
          <a-col :span="24">
            <a-form-item :label="t('routes.role.roleKey')" name="roleKey">
              <a-input
                v-model:value="formState.roleKey"
                :placeholder="t('routes.role.roleKeyPlaceholder')"
              />
            </a-form-item>
          </a-col>
          <a-col :span="24">
            <a-form-item :label="t('routes.role.roleSort')" name="roleSort">
              <a-input-number
                class="!w-[100%]"
                v-model:value="formState.roleSort"
                :placeholder="t('routes.role.roleSortPlaceholder')"
              />
            </a-form-item>
          </a-col>
          <a-col :span="24">
            <a-form-item :label="t('routes.role.status')" name="status">
              <a-radio-group
                v-model:value="formState.status"
                :options="disableOptions"
              />
            </a-form-item>
          </a-col>
          <a-col :span="24">
            <a-form-item :label="t('routes.role.menuIds')" name="menuIds">
              <a-tree
                class="max-h-[360px] overflow-auto border-[#e5e6e7] border-solid border-1px rounded-sm"
                :blockNode="true"
                defaultExpandAll
                checkable
                checkStrictly
                :replace-fields="replaceFields"
                :tree-data="menuOptions"
                v-model:checkedKeys="checkedKeys"
              />
            </a-form-item>
          </a-col>
          <a-col :span="24">
            <a-form-item :label="t('routes.role.remark')" name="remark">
              <a-textarea
                :rows="3"
                v-model:value="formState.remark"
                :placeholder="t('routes.role.remarkPlaceholder')"
              />
            </a-form-item>
          </a-col>
        </a-row>
      </a-form>
    </template>
    <template #footer>
      <a-button type="primary" class="mr-3" @click="handleSubmit">
        {{ t("common.okText") }}
      </a-button>
      <a-button @click="handleClose">{{ t("common.cancelText") }}</a-button>
    </template>
  </BaseDrawer>
</template>
<script lang="ts">
import {
  defineComponent,
  reactive,
  ref,
  onMounted,
  nextTick,
  toRefs,
} from "vue";
import {
  Row,
  Col,
  Form,
  FormItem,
  Input,
  InputNumber,
  RadioGroup,
  Tree,
  Textarea,
} from "ant-design-vue";
import BaseDrawer from "@/components/BaseDrawer/index.vue";
import { getRoleById, addRole, updateRole } from "@/api/admin/system/role";
import { getMenu } from "@/api/admin/system/menu";
import { getDict } from "@/utils/dictFormat";
import useDrawer from "@/hooks/useDrawer";
import { message as Message } from "ant-design-vue";
import { ValidateErrorEntity } from "ant-design-vue/es/form/interface";
import { handleTree } from "@/utils/tools";

import { IRole } from "@/api/admin/system/role/type";
import { IData } from "@/api/admin/system/dict/data/type";
import { IMenu } from "@/api/admin/system/menu/type";
import { useI18n } from "@/hooks/useI18n";

const { t } = useI18n();

interface FormState {
  id: undefined | number;
  roleName: undefined | string;
  roleKey: undefined | string;
  roleSort: undefined | number | string;
  status: undefined | string;
  menuIds: undefined | number[];
  remark: undefined | string;
}
export default defineComponent({
  components: {
    "a-row": Row,
    "a-col": Col,
    "a-form": Form,
    "a-form-item": FormItem,
    "a-input": Input,
    "a-input-number": InputNumber,
    "a-radio-group": RadioGroup,
    "a-tree": Tree,
    "a-textarea": Textarea,
    BaseDrawer,
  },
  emits: ["finished"],
  setup(props, { expose, emit }) {
    const disableOptions = ref<IData[]>([]);
    const checkMenus = () => {
      if ([...checkedKeys.value.checked].length) {
        return Promise.resolve();
      } else {
        return Promise.reject(t("routes.role.menuPermissionIsEmpty"));
      }
    };
    const rules = {
      roleName: [
        {
          required: true,
          message: t("routes.role.roleNameIsEmpty"),
          trigger: "blur",
        },
      ],
      roleKey: [
        {
          required: true,
          message: t("routes.role.roleKeyIsEmpty"),
          trigger: "blur",
        },
      ],
      status: [
        {
          required: true,
          message: t("routes.role.statusIsEmpty"),
          trigger: "change",
        },
      ],
      menuIds: [
        {
          required: true,
          validator: checkMenus,
          trigger: "change",
        },
      ],
    };

    const formRef = ref();
    const formState: FormState = reactive({
      id: undefined,
      roleName: undefined,
      roleKey: undefined,
      roleSort: 1,
      status: "1",
      menuIds: undefined,
      remark: undefined,
    });

    /** 查询菜单树结构 */
    const menuOptions = ref<IMenu[]>([]);
    const checkedKeys = ref<any>({
      checked: [],
    });
    // 树形控件操作
    const replaceFields = {
      children: "children",
      title: "title",
      key: "id",
    };
    const getMenuTreeselect = () => {
      getMenu().then((res) => {
        menuOptions.value = handleTree(res.data.rows, "id", "parentId").tree;
      });
    };

    const { open, drawerTitle, handleOpenDrawer, handleCloseDrawer } =
      useDrawer();

    // 隐藏推窗
    const handleClose = (cb?: () => void) => {
      handleCloseDrawer.value(() => {
        checkedKeys.value.checked = [];
        formState.id = undefined;
        formRef.value.resetFields();
        cb && typeof cb === "function" && cb();
      });
    };
    // 显示推窗
    const handleShow = (row?: IRole) => {
      handleOpenDrawer.value(() => {
        if (row && row.id) {
          drawerTitle.value = t("common.update");
          getRoleById(row.id).then((res) => {
            nextTick(() => {
              Object.keys(formState).forEach((key) => {
                formState[key] = res.data[key];
              });
              const obj = {
                checked: res.data.menus.map((list) => list.id),
                halfChecked: [],
              };
              checkedKeys.value = toRefs(obj);
            });
          });
        } else {
          drawerTitle.value = t("common.add");
        }
      });
    };
    // 表单提交
    const handleSubmit = () => {
      formRef.value
        .validate()
        .then(() => {
          formState.menuIds = [...checkedKeys.value.checked];
          if (formState.id) {
            updateRole(formState).then((res) => {
              handleClose(() => {
                Message.success(res.message);
                emit("finished");
              });
            });
          } else {
            addRole(formState).then((res) => {
              handleClose(() => {
                Message.success(res.message);
                emit("finished");
              });
            });
          }
        })
        .catch((error: ValidateErrorEntity) => {
          console.log("error", error);
        });
    };

    onMounted(async () => {
      disableOptions.value = await getDict("sys_normal_disable");
      disableOptions.value.forEach((item) => {
        item.label = item.dictLabel;
        item.value = item.dictValue;
      });
      getMenuTreeselect();
    });

    expose({
      handleShow,
    });

    return {
      t,
      open,
      drawerTitle,
      formState,
      labelCol: { span: 4 },
      wrapperCol: { span: 20 },
      rules,
      formRef,
      handleClose,
      handleSubmit,
      confirm,
      menuOptions,
      checkedKeys,
      replaceFields,
      disableOptions,
    };
  },
});
</script>
